﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

#pragma once
#include <string>
#include <vector>
#include "IJournalData.h"
#include "OwnerPtr.h"
#include <map>
#include "GcmpJournalInterface.h"

namespace gcmp
{
    class CommandParameters;
    enum class JournalMouseActionType; 
    enum class JournalButtonType;
    enum class JournalKeyActionType;
}
namespace gcmp
{
    class IJournalUiObject;

    /// \brief 日志录制回放数据：回放事件
    ///
    /// 日志回放时会创建一个脚本线程用于解析脚本获取需回放数据，并调用IJournalManager相应接口进行回放
    /// ，回放需要在主线程进行，所以脚本线程获取到的回放数据需要封装到回放事件中，通过消息循环传递给主线程
    /// ，回放事件的传递需要用到消息循环，所以实现类需要多继承所在平台的事件类
    /// ，比如Qt中，回放事件数据的实现类需要多继承QEvent
    class GCMP_JOURNAL_INTERFACE_EXPORT IJournalReplayEvent : public IJournalData
    {
        DEFINE_CAST_DERIVED(IJournalReplayEvent, IJournalData)

    public:
        /// \brief 设置回放事件的名字
        ///
        /// \param[in] commandName 回放事件的名字
        /// \return 运行结果，true成功，false失败
        virtual const bool SetCommandName(const std::wstring &commandName) = 0;

        /// \brief 获取回放事件的名字
        ///
        /// \return 回放事件的名字
        virtual const std::wstring& GetCommandName() const = 0;

        /// \brief 设置事件是否已经被接受
        ///
        /// 若已经被接受，表示事件已经被处理，不会传递给父控件
        /// ，日志事件默认为false
        /// \param[in] isAccepted 事件是否已经被接受
        /// \return 运行结果，true成功，false失败
        virtual bool SetAccepted(bool isAccepted) = 0;

        /// \brief 检查事件是否已经被接受
        ///
        /// 若已经被接受，表示事件已经被处理，不会传递给父控件
        /// ，日志事件默认为false
        /// \return 运行结果，true已经被接受，false没有被接受
        virtual bool IsAccepted() const = 0;

        /// \brief 设置事件对应的日志行号
        ///
        /// \param[in] lineNumber 事件对应的日志行号
        /// \return 运行结果，true成功，false失败
        virtual bool SetLineNumber(int lineNumber) = 0;

        /// \brief 获取事件对应的日志行号
        ///
        /// \return 事件对应的日志行号
        virtual int GetLineNumber() const = 0;
    };

    /// \brief 日志录制回放数据：Command回放事件
    class GCMP_JOURNAL_INTERFACE_EXPORT IJournalCommandReplayEvent : public IJournalReplayEvent
    {
        DEFINE_CAST_DERIVED(IJournalCommandReplayEvent, IJournalReplayEvent)

    public:
        virtual ~IJournalCommandReplayEvent() {}


        /// \brief 获取Command回放事件参数
        ///
        /// \return 日志命令回放事件参数
        virtual gcmp::CommandParameters GetCmdParams() const = 0;
    };

    /// \brief 日志录制回放数据：三维坐标系鼠标操作回放事件
    class GCMP_JOURNAL_INTERFACE_EXPORT IJournalMouseReplayEvent : public IJournalReplayEvent
    {
        DEFINE_CAST_DERIVED(IJournalMouseReplayEvent, IJournalReplayEvent)

    public:
        virtual ~IJournalMouseReplayEvent() {}


        /// \brief 获取鼠标操作的x坐标
        ///
        /// \return 鼠标操作的x坐标
        virtual double GetX() const = 0;
        /// \brief 获取鼠标操作的y坐标
        ///
        /// \return 鼠标操作的y坐标
        virtual double GetY() const = 0;
        /// \brief 获取鼠标操作的z坐标
        ///
        /// \return 鼠标操作的z坐标
        virtual double GetZ() const = 0;

        /// \brief 获取鼠标滚轮操作的幅度
        ///
        /// \return 鼠标滚轮操作的幅度，无滚轮操作则返回0
        virtual int GetDelta() const = 0;

        /// \brief 获取鼠标操作事件类型
        ///
        /// \return 鼠标事件类型
        virtual const JournalMouseActionType GetMouseActionType() const = 0;

        /// \brief 获取鼠标按键类型
        ///
        /// \return 鼠标按键类型
        virtual const JournalButtonType GetMouseButtonType() const = 0;


    };

    /// \brief 日志录制回放数据：键盘操作回放事件
    class GCMP_JOURNAL_INTERFACE_EXPORT IJournalKeyReplayEvent : public IJournalReplayEvent
    {
        DEFINE_CAST_DERIVED(IJournalKeyReplayEvent, IJournalReplayEvent)

    public:
        virtual ~IJournalKeyReplayEvent() {}


        /// \brief 获取键盘操作的键值
        ///
        /// \return 键盘操作的键值
        virtual int GetCode() const = 0;

        /// \brief 获取键盘操作的类型
        ///
        /// \return 键盘操作类型
        virtual const JournalKeyActionType GetKeyActionType()const = 0;
    };

    /// \brief 日志录制回放数据：用户UI交互操作回放事件
    class GCMP_JOURNAL_INTERFACE_EXPORT IJournalUIReplayEvent : public IJournalReplayEvent
    {
    public:
        virtual ~IJournalUIReplayEvent() {}

        /// \brief 获取用户UI交互操作回放事件的参数
        ///
        /// \return 用户UI交互操作回放事件的参数
        virtual std::wstring GetParameters() const = 0;

        /// \brief 是否为自定义的子控件所触发的事件
        ///
        /// \return 是：true 否：false
        virtual bool IsCustomChildWidget() const = 0;
    };

    /// \brief 日志录制回放数据：Definition回放事件
    class GCMP_JOURNAL_INTERFACE_EXPORT IJournalDefinitionReplayEvent : public IJournalReplayEvent
    {
    public:
        virtual ~IJournalDefinitionReplayEvent() {}

        /// \brief 获取Definition类型
        ///
        /// \return Definition类型
        virtual std::wstring GetDefinitionType() const = 0;

        /// \brief 获取DefinitionId
        ///
        /// \return DefinitionId
        virtual std::wstring GetDefinitionId() const = 0;

        /// \brief 获取DefinitionId
        ///
        /// \return DefinitionId
        virtual std::map<std::wstring, std::wstring> GetDefinitionStates() const = 0;
    };

    /// \brief 日志录制回放数据：键盘操作回放事件
    class GCMP_JOURNAL_INTERFACE_EXPORT IJournalErrorReplayEvent : public IJournalReplayEvent
    {
    public:
        virtual ~IJournalErrorReplayEvent() {}

        /// \brief 获取回放失败的错误信息
        ///
        /// \return 回放失败的错误信息
        virtual std::wstring GetErrorMessage() const = 0;
    };
}

